import { ref, onMounted, getCurrentInstance } from "vue"
import { smartBack, cloudIdToUrl, handleApiResponse } from '@/utils/common.js'
import { onLoad } from '@dcloudio/uni-app'

export function useTableSearch(opt) {
	// 默认数据
	const orderByMapping = {
		ascending:'asc',
		descending: 'desc',
	}
	
	// searchform 是列表查询条件
	// getList 即云对象获取列表数据的方法，例如：uniCloud.importObject('iss-wallpaper-classify').getList(query.value)
	const { title, tableRef, searchform, getList, 
	getParentData, columnToggle, remove, onGetDataSucceed, dictsRef,
	dialogRef, formRef, initFormData, getFormData, add, update } = opt 
	// 用来存储查询条件
	const query = ref({
		page:1,
		pageSize: 10,
		orderFiled:'sort',
		orderDirection:'asc',
		...searchform
	})
	// 用来存储查询结果数据
	const tableData = ref({
		parent: {},
		list: [],
		total: 0,
		selectedIndexArray: []
	})
	
	// 如果当前列表为子列表，则会有父页面跳转带过来参数：id, from 
	const instance = ref(null)
	const backUrl = ref('')
	onLoad(async e => {
		if(e.id) {
			tableData.value.parent._id = e.id
			if(opt.getParentData && typeof opt.getParentData == 'function') {
				const pData = await opt.getParentData(e.id)
				tableData.value.parent = pData
			}
		}
		if(e.from) {
			backUrl.value =  e.from.startsWith('/') ? e.from : '/'+e.from
		}
	    // instance.value = getCurrentInstance().proxy
	})
	
	// 根据query获取列表数据
	const getData = async (page) => {
		try {
			if(page){
				query.value.page = page
			}
			// console.log('query.value=', query.value)
			const data = await handleApiResponse(() => getList(query.value));
			tableData.value.list = data.list
			tableData.value.total = data.total
			if(opt.onGetDataSucceed && typeof opt.onGetDataSucceed == 'function') {
				opt.onGetDataSucceed(data)
			}
			tableRef.value.clearSelection()
		} catch (error) {
			uni.showToast({
				title: error.message,
				duration: 2000
			});
			console.error(error)
		}
	}
	
	/**
	 * 批量获取数据字典
	 * @param {Ref<Array<Object>>} dictsRef - 数据字典引用数组的Ref对象，每个对象至少包含type字段
	 * @returns {Promise<void>}
	 */
	const getDicts = async (dictsRef) => {
		
	  if (!dictsRef || !dictsRef.value || !Array.isArray(dictsRef.value)) {
	    // console.error('dictsRef 必须是一个包含数组的Ref对象')
	    return
	  }
	
	  const dicts = dictsRef.value
	
	  try {
	    // 收集所有需要查询的字典类型
	    const dictTypes = dicts.map(item => item.type).filter(Boolean)
	    
	    if (dictTypes.length === 0) {
	      console.warn('没有有效的字典类型需要查询')
	      return
	    }
	
	    // 批量查询字典数据
	    const db = uniCloud.database()
	    const res = await db.collection('iss-wallpaper-dict')
	      .where({
	        type: db.command.in(dictTypes),
	        status: true
	      })
	      .get()

		dictsRef.value = res.result.data
		
	    // 按类型组织查询结果，并过滤options中status=true的数据
	        const dictDataMap = new Map()
	        res.result.data.forEach(item => {
	          if (item.type && item.options) {
	            // 过滤options，只保留status=true的项
	            const filteredOptions = item.options
	              .filter(option => option.status === true)
	              .map(option => ({
	                value: option.code,
	                text: option.text,
	                description: option.description,
	                // 保留其他可能需要的字段
	                ...option
	              }))
	            
	            // console.log(`处理后的 ${item.type} 选项:`, filteredOptions)
	            dictDataMap.set(item.type, filteredOptions)
	          }
	        })
	    
	        // 将查询结果赋值回原对象
	        dictsRef.value.forEach(dict => {
	          if (dict.type && dictDataMap.has(dict.type)) {
	            // 保留原对象的其他属性，只覆盖options字段
	            dict.options = dictDataMap.get(dict.type)
	          } else {
	            // 如果没有查询到对应的字典数据，设置空数组
	            dict.options = []
	          }
	        })
	    
	        // console.log('最终字典数据:', dictsRef.value)
	
	  } catch (e) {
	    console.error('批量获取数据字典失败:', e)
	    // 出错时将所有字典的options设为空数组
	    dicts.forEach(dict => {
	      dict.options = []
	    })
	    throw e
	  }
	}
	
	// 页面加载时获取数据
	onMounted(() => {
		getData(1)
		// 获取数据字典
		getDicts(dictsRef)
	})
	
	/**
	 * 根据类型获取字典对象
	 * @param {string} type - 字典类型
	 * @returns {Object|null} 返回对应的字典对象，找不到则返回null
	 */
	const getDictByType = (type) => {
	  // 确保 dictsRef.value 存在且是数组
	  if (!dictsRef.value || !Array.isArray(dictsRef.value)) {
	    console.warn('dictsRef.value 不是一个有效数组')
	    return null
	  }
	
	  // 查找匹配的字典类型
	  const dict = dictsRef.value.find(item => item.type === type)
	  
	  if (!dict) {
	    console.warn(`未找到类型为 ${type} 的字典`)
	    return null
	  }
	
	  return {
	    type: dict.type,
	    options: dict.options || [], // 确保总是返回数组
	    // 保留字典的其他属性
	    ...dict
	  }
	}
	
	// 获取对应option选项的文本
	const getDictText = (type, code) => {
		try {
			const dict = getDictByType(type)
			if(dict && dict.options) {
				const option = dict.options.find(item=>item.code == code)
				return option.text || ''
			}
		} catch (error) {
			return ''
		}
	}
	
	const toggleFieldChange = async (id,fieldName) => {
		try {
			const res = await columnToggle(id,fieldName)
			uni.showToast({
				title: fieldName + "状态切换成功！"
			})
		} catch (error) {
			//TODO handle the exception
		}
	}
	
	// table查询条件变化事件
	const filterChange = (e, name) => {
		query.value[name] = e.filter
		getData(1)
	}
	
	// 排序变化事件
	const sortChange = (e, name) => {
		if (e.order) {
			query.value.orderFiled = name
			query.value.orderDirection = orderByMapping[e.order]
		} else {
			query.value.orderFiled = ''
		}
		tableRef.value.clearSelection()
		setTimeout(()=>{
			getData()
		},300)
	}
	
	// table多选事件
	const selectionChange = (e) => {
		tableData.value.selectedIndexArray = e.detail.index
	}
	// 分页控件，页码变化事件，比如：由第一页变化到第二页
	const onPageChange = (e) => {
		query.value.page = e.current
		getData()
	}
	// 分页控件，页码发生变化，比如：每页10条记录，变化到每页20条记录
	const changeSize = (e) => {
		query.value.pageSize = e
		getData()
	}
	
	// 查看图片事件
	const  previewImage = (currentUrl, picurlField) => {
		let list = tableData.value.list
		// 收集所有图片的 URL
		const urls = list.map(item => cloudIdToUrl(item[picurlField]));
		uni.previewImage({
			current: cloudIdToUrl(currentUrl),  // 当前点击的图片
			urls: urls,           // 所有图片的 URL 数组
			indicator: 'number'  // 支持显示指示点
		});
	}
	
	// 批量删除，根据选中的记录批量删除
	const removeDataByIds = async (ids) => {
		try {
			const res = await uni.showModal({
				title: '提示',
				content: '确定进行删除操作？'
			})
			if(res.confirm) {
				// 如果没有主动转入ids，则以选择的tableData.value.selectedIndexArray为准
				if(!ids || ids.length == 0) {
					ids = [];
					[...tableData.value.selectedIndexArray].forEach(index=>{
						// 注意，此处一般要求列表的主键为_id，但类似像数据字典的options，可能以code为主键，因此做特殊处理
						ids.push(tableData.value.list[index]._id||tableData.value.list[index].code)
					});
				}
				const res = await remove(ids)
				// console.log(res)
				uni.showToast({
					title: "删除成功！"
				})
				let {list , total} = tableData.value
				let {page, pageSize} = query.value
				// 如果当前页面是列表最后一页，且当前页面的所有数据都被删除掉，则页面需要向后退一页，再刷新数据
				if(list.length == ids.length && total == (page-1)*pageSize+list.length && page>1) {
					query.value.page --
				}
				tableRef.value.clearSelection()
				getData()
			} 
		} catch (error) {
			//TODO handle the exception
			console.log('removeDataByIds-error', error)
		}
	}
	
	/**
	 * 增强版跳转方法，自动添加来源页面参数
	 * @param {string} url 目标页面路径
	 * @param {boolean} [clear=true] 是否清除页码（用于列表刷新）
	 * @param {boolean} [addFrom=true] 是否自动添加来源页面参数
	 */
	const navigateTo = (url, clear = true, addFrom = true) => {
	  // 获取当前页面路由
	  const pages = getCurrentPages()
	  const currentPage = pages[pages.length - 1]
	  const currentRoute = currentPage?.route || ''
	  
	  // 处理URL，添加from参数
	  let finalUrl = url
	  if (addFrom && currentRoute) {
		const separator = url.includes('?') ? '&' : '?'
		finalUrl = `${url}${separator}from=${encodeURIComponent(currentRoute)}`
	  }
	  
	  // 执行跳转
	  uni.navigateTo({
		url: finalUrl,
		events: {
		  refreshData: (e) => {
			if (clear) {
			  getData(1) // 刷新并回到第一页
			} else {
			  getData() // 普通刷新
			}
		  }
		}
	  })
	}
	
	// ##########以下为dialog相关定义###############################
	const formData = ref({})
	const formModel = ref('add') // 表单模式，'add'为新增，'mod' 为编辑模式 
	// 打开编辑窗口
	const showDialog = async (id, pid) => {
		if(id) {
			const res = await getFormData(id, pid)
			formData.value = res.data
			formModel.value = 'mod'
		} else {
			formData.value = initFormData
			formModel.value = 'add'
		}
		dialogRef.value.open()
	}
	// 关闭窗口
	const closeDialog = () => {
		formData.value = initFormData
		formModel.value = 'add'
		dialogRef.value.close()
	}
	
	// 提交窗口
	const confirmDialog = async (pid) => {
		// console.log('confirmDialog')
		try {
		// 验证表单
		await formRef.value.validate()
				
		// 表单验证通过后，在提交formData数据之前要做的同步数据操作，例如此处的图片上传及删除
		if(opt.beforeSubmitOptAsync && typeof opt.beforeSubmitOptAsync == 'function') {
			await opt.beforeSubmitOptAsync(formRef.value)
		}
				
		  // 继续提交表单数据
		  uni.showLoading({
		    title: '数据提交中...',
		    mask: true
		  })
		  
		  const copy = JSON.parse(JSON.stringify(formData.value))
		  
		  let res = null
		  if (formModel.value == 'mod') {
		    res = await update(copy, pid)
		  } else {
		    res = await add(copy, pid)
		  }
		  
		  uni.showToast({
		    title: (copy._id ? "编辑" : "新增") + title+"成功"
		  })
		  setTimeout(()=>{
			  
			  getData()
		  },500)
		} catch (error) {
		  console.error('提交失败:', error)
		  uni.showToast({
		    icon: 'none',
		    title: error.message || '提交失败'
		  })
		} finally {
		  uni.hideLoading()
		}
	}
	
	return {
		query,
		tableData,
	    getData,
		removeDataByIds,
		toggleFieldChange,
		selectionChange,
	    onPageChange,
		changeSize,
	    filterChange,
		sortChange,
	    previewImage,
		navigateTo,
		smartBack,
		getDictByType,
		getDictText,
		showDialog,
		closeDialog,
		confirmDialog,
		formData
	}
}

export function useForm(opt) {
	const { title, formRef, formData, doc, add, update, onGetDataSucceed, beforeSubmitOptAsync } = opt 
	
	const instance = ref(null)
	const backUrl = ref('')
	const formModel = ref('add') // 表单模式，'add'为新增，'mod' 为编辑模式
	
	onLoad(e => {
		if(e.id) {
			formModel.value = 'mod'
			opt.doc(e.id).then( res=>{
			  formData.value = res.data
			  // 当formData获取数据完成后，在前端页面需要对数据
			  if(opt.onGetDataSucceed && typeof opt.onGetDataSucceed == 'function') {
				  opt.onGetDataSucceed(res.data)
			  }
			})
		}
		if(e.from) {
			backUrl.value =  e.from.startsWith('/') ? e.from : '/'+e.from
		}
	    instance.value = getCurrentInstance().proxy
	})
	
	// 综合考虑各种情况处理后的返回
	const navigateBack = (refresh=true) => {
		if(!refresh) {
			smartBack(backUrl.value)
			return
		}
		formModel.value=='mod' ? smartBack(backUrl.value) : uni.reLaunch({ url: backUrl.value })
	}
	
	// 提交表单
	const submitForm = async () => {
	  try {
	    // 验证表单
	    await formRef.value.validate()
		
		// 表单验证通过后，在提交formData数据之前要做的同步数据操作，例如此处的图片上传及删除
		if(opt.beforeSubmitOptAsync && typeof opt.beforeSubmitOptAsync == 'function') {
			await opt.beforeSubmitOptAsync(formRef.value)
		}
		
	    // 继续提交表单数据
	    uni.showLoading({
	      title: '数据提交中...',
	      mask: true
	    })
	    
	    const copy = JSON.parse(JSON.stringify(formData.value))
	    
	    let res = null
	    if (copy._id) {
	      res = await update(copy)
	    } else {
	      res = await add(copy)
	    }
	    
	    if (res.code == 200) {
	      uni.showToast({
	        title: (copy._id ? "编辑" : "新增") + title+"成功"
	      })
	      const eventChannel = instance.value.getOpenerEventChannel()
	      if (eventChannel.emit) eventChannel.emit('refreshData', copy)
	      setTimeout(() => {
	        navigateBack()
	      }, 1000)
	    } else {
	      uni.showToast({
	        icon: 'none',
	        title: res.msg
	      })
	    }
	  } catch (error) {
	    console.error('提交失败:', error)
	    uni.showToast({
	      icon: 'none',
	      title: error.message || '提交失败'
	    })
	  } finally {
	    uni.hideLoading()
	  }
	}
	
	return {
		backUrl,
		submitForm,
		navigateBack
	}
}